home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / cdity / MRQ.lha / MRQ / Source / config.c next >
C/C++ Source or Header  |  2000-10-16  |  9KB  |  366 lines

  1. /* config.c
  2. ** Handles the processing of MRQ's configfile
  3. **
  4. ** ©1997-2000 by Matthias.Bethke <Matthias.Bethke@gmx.net>
  5. ** You are free to modify this source or use parts of it in your
  6. ** own programs as long as they are distributed as freeware.
  7. */
  8.  
  9. /* $Id: config.c 1.4 2000/10/15 13:29:23 msbethke Exp msbethke $
  10. **
  11. ** $Log: config.c $
  12. ** Revision 1.4  2000/10/15 13:29:23  msbethke
  13. ** oops - forgot an argument to the warning message...
  14. **
  15. ** Revision 1.3  2000/10/15 12:51:25  msbethke
  16. ** Additional warning in FillDefaultClass()
  17. **
  18. ** Revision 1.2  2000/01/25 17:28:45  msbethke
  19. ** Adapted to new header names
  20. **
  21. ** Revision 1.1  2000/01/25 17:20:15  msbethke
  22. ** Initial revision
  23. **
  24. **
  25. */
  26.  
  27. #include <proto/exec.h>
  28. #include <proto/dos.h>
  29. #include <proto/locale.h>
  30. #include <proto/intuition.h>
  31. #include <exec/memory.h>
  32. #include <lib/mb_utils.h>
  33. #include <string.h>
  34. #include <stdlib.h>
  35. #include <ctype.h>
  36. #include "mrq.h"
  37. #include "config.h"
  38. #include "gfxfiles.h"
  39.  
  40.  
  41. /* local protos */
  42. static STRPTR AddMiscClassString(STRPTR,struct MRQConfig*,STRPTR*,STRPTR);
  43. static STRPTR AddLocalizedString(STRPTR,LONG,struct MRQConfig*,ULONG);
  44. static STRPTR AddMRQString(STRPTR,struct MRQConfig*,ULONG);
  45. static void FillDefaultClass(struct MRQConfig*);
  46. static STRPTR MkImagePath(STRPTR);
  47.  
  48.  
  49.  
  50. struct MRQConfig *ReadMRQConfig(STRPTR Name)
  51. {
  52. STRPTR err=NULL;
  53. static struct MRQConfig Config={0};
  54.  
  55.     prdebug("ReadMRQConfig()\n");
  56.     if(Config.mc_MemPool = CreatePool(MEMF_ANY | MEMF_CLEAR,1024,512))
  57.     {
  58.     BPTR fh;
  59.  
  60.  
  61.         if(ttVars.AvoidTasks)        // store AVOIDTASKS pattern preparsed
  62.         {
  63.         STRPTR t;
  64.         LONG destlen;
  65.  
  66.             destlen = strlen(ttVars.AvoidTasks)*2+2;
  67.             if(t = AllocVecPooled(Config.mc_MemPool,destlen))
  68.             {
  69.                 if(ParsePattern(ttVars.AvoidTasks,t,destlen) == -1)
  70.                 {
  71.                     err = MRQERROR_BADPATTERN;
  72.                 } else ttVars.AvoidTasks = t;
  73.             } else err=MRQERROR_NOMEMORY;
  74.         }
  75.  
  76.         if(ttVars.IButtonsByText)
  77.         {
  78.         STRPTR s;
  79.  
  80.             if(s = AllocVecPooled(Config.mc_MemPool,strlen(ttVars.IButtonsByText)+1))
  81.             {
  82.                 strcpy(s,ttVars.IButtonsByText);
  83.                 Config.mc_IButton_Yes.mib_Text    = strtok(s,",");
  84.                 Config.mc_IButton_No.mib_Text        = strtok(NULL,",");
  85.                 Config.mc_IButton_Cancel.mib_Text= strtok(NULL,",");
  86.                 if(Config.mc_IButton_Yes.mib_Text &&
  87.                     Config.mc_IButton_No.mib_Text    &&
  88.                     Config.mc_IButton_Cancel.mib_Text)
  89.                 {
  90.                     prdebug("ImageButton matchtexts:\n\tYes   : %s\n\tNo    : %s\n\tCancel: %s\n",
  91.                         Config.mc_IButton_Yes.mib_Text,
  92.                         Config.mc_IButton_No.mib_Text,
  93.                         Config.mc_IButton_Cancel.mib_Text);
  94.                 } else
  95.                 {
  96.                     prdebug("Specify exactly one pattern for YES, NO and CANCEL,\nseparated by commas, for IBUTTONSBYTEXT!\n");
  97.                     ttVars.IButtonsByText = NULL;
  98.                     FreeVecPooled(Config.mc_MemPool,s);
  99.                 }
  100.             } else err = MRQERROR_NOMEMORY;
  101.         }
  102.         ReadImageButtons(&Config);
  103.         FillDefaultClass(&Config);
  104.  
  105.         NewList((struct List*)(&Config.mc_ClassList));
  106.  
  107.         if(!err && (fh = Open(Name,MODE_OLDFILE)))
  108.         {
  109.         struct RDArgs *rda, *fargs;
  110.  
  111.             prdebug("Reading configfile\n");
  112.             if(rda = AllocDosObjectTagList(DOS_RDARGS,NULL))
  113.             {
  114.             UBYTE LBuf[512];
  115.             struct Arguments args;
  116.             LONG line=0;
  117.             ULONG Flags;
  118.  
  119.                 while(FGets(fh,LBuf,sizeof(LBuf)) && (!err))
  120.                 {
  121.                     line++;
  122.                     memset(&args,0,sizeof(args));
  123.  
  124.                     rda->RDA_Source.CS_Buffer = LBuf;
  125.                     rda->RDA_Source.CS_Length = strlen(LBuf);
  126.                     rda->RDA_Source.CS_CurChr = 0;
  127.                     rda->RDA_Buffer = NULL;
  128.                     rda->RDA_BufSiz = 0;
  129.                     rda->RDA_Flags  = RDAF_NOPROMPT;
  130.  
  131.                     if(LBuf[rda->RDA_Source.CS_Length-1] != '\n')
  132.                         LBuf[rda->RDA_Source.CS_Length++] = '\n';
  133.  
  134.                     if(!(fargs = ReadArgs(CONFIG_RDAPATTERN,(LONG*)(&args),rda)))
  135.                     {
  136.                         prdebug("Parse error in line %ld, continuing...\n",line);
  137.                         continue;
  138.                     }
  139.  
  140.  
  141.                     Flags = 0;
  142.                     if(args.Substring)    Flags |= MSF_SUBSTRING;
  143.                     if(args.Pattern)        Flags |= MSF_PATTERN;
  144.                     if(args.NoCase)        Flags |= MSF_NOCASE;
  145.                     if(args.Formatted)    Flags |= MSF_FORMATTED;
  146.                     if((Flags & MSF_SUBSTRING) && (Flags & MSF_PATTERN))
  147.                     {
  148.                         prdebug("Warning: PATTERN and SUBSTRING are mutually exclusive (line %ld)!\n",(LONG)line);
  149.                         Flags &= ~MSF_SUBSTRING;
  150.                     }
  151.  
  152.  
  153.                     if(args.NewClass)
  154.                     {
  155.                     struct MRQEventClass *class;
  156.  
  157.                         if(class = AllocVecPooled(Config.mc_MemPool,sizeof(struct MRQEventClass)))
  158.                         {
  159.                             NewList((struct List*)(&(class->mec_StringList)));
  160.                             AddTail((struct List*)(&Config.mc_ClassList),(struct Node*)class);
  161.                         } else err = MRQERROR_NOMEMORY;
  162.                     }
  163.  
  164.                     else if(args.Locale)
  165.                     {
  166.                     STRPTR LocName;
  167.                     int ArgNum;
  168.                     
  169.                         LocName = *args.Locale;
  170.  
  171.                         if(args.Locale[1])
  172.                         {
  173.                         LONG StringNum;
  174.  
  175.                             for(ArgNum=1; args.Locale[ArgNum] && !err ; ArgNum++)
  176.                             {
  177.                                 StringNum = strtol(args.Locale[ArgNum],NULL,10);
  178.                                 err = AddLocalizedString(LocName,StringNum,&Config,Flags);
  179.                             }
  180.                         } else prdebug("Dubious or missing parameter in line %ld: %s\n",line,LocName);
  181.                     }
  182.  
  183.                     else if(args.String)
  184.                     {
  185.                         if(err = AddMRQString(args.String,&Config,Flags)) break;
  186.                     }
  187.  
  188.                     else if(args.Image)
  189.                     {
  190.                     STRPTR tmpimgname;
  191.                     struct MRQImage *img;
  192.  
  193.                         tmpimgname = MkImagePath(args.Image);
  194.                         img = &(((struct MRQEventClass*)(Config.mc_ClassList.mlh_TailPred))->mec_Image);
  195.  
  196.                         if(args.Transparent)    img->mi_Flags |= MIF_TRANSPARENT;
  197.                         if(args.Animation)    img->mi_Flags |= MIF_ANIMATION;
  198.     
  199.                         if(args.Preload)
  200.                         {
  201.                             if(PreloadImage(tmpimgname,img))
  202.                             {
  203.                                 prdebug("Preloaded image '%s'\n",args.Image);
  204.                             } else err = MRQERROR_LOADIMAGE;
  205.                         } else
  206.                         {
  207.                             AddMiscClassString(tmpimgname,&Config,(STRPTR*)(&img->mi_Object),"an image");
  208.                             img->mi_Flags |= MIF_FILENAME;
  209.                         }
  210.                         FreeVec(tmpimgname);
  211.                     }
  212.  
  213.                     else if(args.RxPort || args.RxCmd)
  214.                     {
  215.                         if(args.RxPort)
  216.                         {
  217.                             err = AddMiscClassString(args.RxPort,&Config,&(((struct MRQEventClass*)(Config.mc_ClassList.mlh_TailPred))->mec_RxPortName),"an ARexx port");
  218.                         }
  219.  
  220.                         if(args.RxCmd && !err)
  221.                         {
  222.                             err = AddMiscClassString(args.RxCmd,&Config,&(((struct MRQEventClass*)(Config.mc_ClassList.mlh_TailPred))->mec_RxCmdString),"an ARexx command");
  223.                         }
  224.                     }
  225.                     FreeArgs(fargs);
  226.                 }
  227.                 FreeDosObject(DOS_RDARGS,rda);
  228.             } else err = MRQERROR_NOMEMORY;
  229.             Close(fh);
  230.         } else err = MRQERROR_NOCONFIGFILE;
  231.     } else err=MRQERROR_NOMEMORY;
  232.  
  233.     if(err || IsListEmpty((struct List*)(&Config.mc_ClassList)))
  234.     {
  235.         DeletePool(Config.mc_MemPool);
  236.         prdebug(err ?    "Initialization error: %s!\n" :
  237.                             "Config file doesn't contain any class definitions!\n",err);
  238.         return NULL;
  239.     } else prdebug("Configfile read OK\n");
  240.     return &Config;
  241. }
  242.  
  243. void FreeMRQConfig(struct MRQConfig *cfg) 
  244. {
  245.     FreeImageButtons(cfg);
  246.     FreePreloaded(cfg);
  247.     DeletePool(cfg->mc_MemPool);
  248. }
  249.  
  250. static STRPTR AddLocalizedString(STRPTR CatName, LONG StringNum, struct MRQConfig *cfg, ULONG Flags)
  251. {
  252. struct Catalog *cat;
  253. STRPTR ret=NULL;
  254.  
  255.     if(cat = OpenCatalogA(NULL,CatName,NULL))
  256.     {
  257.     STRPTR s;
  258.  
  259.         if(s=GetCatalogStr(cat,StringNum,NULL))
  260.         {
  261.             ret = AddMRQString(s,cfg,Flags);
  262.         } else
  263.         {
  264.             prdebug("Can't read string #%ld from catalog %s!\n",StringNum,CatName);
  265.             ret = "GetCatalogStr() failed";
  266.         }
  267.         CloseCatalog(cat);
  268.     }
  269.     return ret;
  270. }
  271.  
  272. static STRPTR AddMRQString(STRPTR s, struct MRQConfig *cfg, ULONG Flags)
  273. {
  274. struct MRQString *mstr;
  275. ULONG slen;
  276.  
  277.     if(cfg->mc_ClassList.mlh_TailPred == (struct MinNode*)(&cfg->mc_ClassList))
  278.     {
  279.         prdebug("Can't add a string without a class!\n");
  280.         return MRQERROR_CONFIGFORMAT;
  281.     }
  282.  
  283.     slen = strlen(s)+2;
  284.     if(Flags & MSF_PATTERN) slen <<= 1;
  285.  
  286.     if(mstr = AllocVecPooled(cfg->mc_MemPool,sizeof(struct MRQString)+slen))
  287.     {
  288.         if(Flags & MSF_PATTERN)
  289.         {
  290.         LONG iswild;
  291.  
  292.             if(Flags & MSF_NOCASE) iswild = ParsePatternNoCase(s,(STRPTR)(mstr+1),slen);
  293.             else iswild = ParsePattern(s,(STRPTR)(mstr+1),slen);
  294.             if(iswild == -1)
  295.             {
  296.                 FreeVecPooled(cfg->mc_MemPool,mstr);
  297.                 return MRQERROR_BADPATTERN;
  298.             }
  299.         } else
  300.         {
  301.             strcpy((char*)(mstr+1),s);
  302.         }
  303.  
  304.         mstr->ms_String = (STRPTR)(mstr+1);
  305.         mstr->ms_Flags  = Flags;
  306.  
  307.         AddTail((struct List*)(&((struct MRQEventClass*)(cfg->mc_ClassList.mlh_TailPred))->mec_StringList),
  308.                     (struct Node*)mstr);
  309.         return NULL;
  310.     } else return MRQERROR_NOMEMORY;
  311.     return FALSE;
  312. }
  313.  
  314. static STRPTR AddMiscClassString(STRPTR s, struct MRQConfig *cfg, STRPTR *dest, STRPTR ItemDesc)
  315. {
  316. STRPTR ret=NULL;
  317.     if(cfg->mc_ClassList.mlh_TailPred != (struct MinNode*)(&cfg->mc_ClassList))
  318.     {
  319.         if(!(*dest))
  320.         {
  321.             if(*dest = AllocVecPooled(cfg->mc_MemPool,strlen(s)+1))
  322.             {
  323.                 strcpy(*dest,s);
  324.                 return NULL;
  325.             } else ret = MRQERROR_NOMEMORY;
  326.         }
  327.     } else prdebug("Can't add %s without a class!\n",ItemDesc);
  328.     return ret;
  329. }
  330.  
  331. static STRPTR MkImagePath(STRPTR name)
  332. {
  333. STRPTR dest;
  334.  
  335.     if(strchr(name,':') || (!(ttVars.DefImageDir)))
  336.     {
  337.         if(dest = AllocVec(strlen(name)+1,MEMF_ANY))
  338.             strcpy(dest,name);
  339.     } else
  340.     {
  341.     ULONG len;
  342.  
  343.         if(dest = AllocVec(len=strlen(name)+strlen(ttVars.DefImageDir)+3,MEMF_ANY))
  344.         {
  345.             strcpy(dest,ttVars.DefImageDir);
  346.             if(!AddPart(dest,name,len))
  347.             {
  348.                 FreeVec(dest);
  349.                 dest = NULL;
  350.             }
  351.         }
  352.     }
  353.     if(dest == NULL) prdebug("MkImagePath() failed!\n");
  354.     return dest;
  355. }
  356.  
  357. static void FillDefaultClass(struct MRQConfig *cfg)
  358. {
  359. STRPTR tmpimgname, defname="MRQ_DefaultImage";
  360.  
  361.     tmpimgname = MkImagePath(defname);
  362.     if(!PreloadImage(tmpimgname,&cfg->mc_DefClass.mec_Image))
  363.         prdebug("Warning: can't load default image\n\t(%s)\n\tunrecognized requesters will not be promoted!\n",tmpimgname);
  364.     FreeVec(tmpimgname);
  365. }
  366.